## Warning: We recommend using the dplyr::*_join() family of functions instead.
## Warning: `group_by_()` was deprecated in dplyr 0.7.0.
## Please use `group_by()` instead.
## See vignette('programming') for more help
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
## Warning: sf layer has inconsistent datum (+proj=longlat +datum=NAD83 +no_defs).
## Need '+proj=longlat +datum=WGS84'
## Warning: We recommend using the dplyr::*_join() family of functions instead.
## Warning: sf layer has inconsistent datum (+proj=longlat +datum=NAD83 +no_defs).
## Need '+proj=longlat +datum=WGS84'

hh_income brackets with 30% or more spent on rent

Number of Eligible household by amount of hh_income with 30% spent on rent category

Number of Eligible household with hh_income less than 75k with 30% spent on rent.

Proportion of household with hh_income less than 75k and 30% spent on rent NOT receiving assisstance.

Number of households spending above 30% and 50% of hh_income on rent.

Proportion of households spending above 30% and 50% of hh_income on rent and not receiving assitance.

30% or more spent on rent with rent category

Number of Eligible household by percentage of hh_income spent on rent category

## `summarise()` has grouped output by 'county'. You can override using the
## `.groups` argument.

Number of Eligible household vs Number reported for Kent

Number of Eligible household vs Number reported for NC

Number of Eligible household vs Number reported for Sussex

Number of household eligible for receiving rental assistance by housing vouchers

Number of household receiving rental assistance by housing vouchers

Proportion of household not receiving rental assistance by housing vouchers

Exploring the disparity between 30% vs 50%

acs_hud_de_geojoined_prop <- acs_hud_de_geojoined %>%
    # Calculate difference eligible renters 
    mutate(diff_30_50 = eligible_renters - eligible_renters_50pct) %>%
    rowwise() %>%
    mutate(rent_30to40 = sum(rent_30E, rent_35E, rent_40E),
           rent_50 = rent_50E) %>%
    ungroup %>%
    # calculate proportions
    mutate(rent_30to40_prop = rent_30to40 / renter_householdersE,
           rent_50_prop = rent_50 / renter_householdersE) %>%
    mutate(eligible_renters_30pct_prop = eligible_renters / renter_householdersE,
           eligible_renters_50pct_prop = eligible_renters_50pct / renter_householdersE,
           diff_prop_30_50 = eligible_renters_30pct_prop - eligible_renters_50pct_prop)

Counts

scatter_30_50 <- acs_hud_de_geojoined_prop %>%
    ggplot(aes(x = eligible_renters, y = eligible_renters_50pct,
               label = census_tract_label, color = diff_30_50)) +
        geom_smooth(method = "lm") + 
    geom_point() +
    xlab("Households paying 30%+ on rent") +
    ylab("Households paying 50%+ on rent")

ggplotly(scatter_30_50)
## `geom_smooth()` using formula 'y ~ x'
barplot_30_50_diff <- acs_hud_de_geojoined_prop %>%
    ggplot(aes(x = reorder(tract, diff_30_50), y = diff_30_50)) + 
    geom_bar(stat = "identity") +
    xlab("Census Tracts") +
    ylab("Difference between 30% vs 50%")
barplot_30_50_diff %>% ggplotly()

Proportions

50 ~ 30

library(broom)
acs_hud_de_geojoined_prop <- acs_hud_de_geojoined_prop %>% 
    mutate(row_number = row_number() %>% as.character())

scatter_50_30_prop <- acs_hud_de_geojoined_prop %>% 
    ggplot(aes(x = eligible_renters_30pct_prop, y = eligible_renters_50pct_prop,
               label = census_tract_label, color = diff_prop_30_50)) +
        geom_smooth(method = "lm") + 
    geom_point() +
    xlab("Proportions of households paying 30%+ on rent") +
    ylab("Proportions of households paying 50%+ on rent")

scatter_50_30_prop %>% ggplotly()
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 4 rows containing non-finite values (stat_smooth).
# 50 ~ 30
lm_50_30 <- acs_hud_de_geojoined_prop %>%
    lm(data = ., eligible_renters_50pct_prop ~ eligible_renters_30pct_prop)

aug_50_30 <- lm_50_30 %>% 
    augment()


resid_plot_50_30 <- aug_50_30 %>%
    left_join(acs_hud_de_geojoined_prop %>% select(row_number, tract),
              by = c(".rownames" = "row_number")) %>% 
    ggplot(aes(x = eligible_renters_30pct_prop, y = .std.resid, label = tract)) + 
    geom_point() +
    geom_hline(yintercept = 0) +
    ylab("Standardized Residual") +
    xlab("Proportion of renters paying 30%+ on rent")

resid_plot_50_30 %>%
    ggplotly()

30 ~ 50

scatter_30_50_prop <- scatter_50_30_prop +
    coord_flip()

scatter_30_50_prop %>% ggplotly()
## `geom_smooth()` using formula 'y ~ x'
## Warning: Removed 4 rows containing non-finite values (stat_smooth).
# 30 ~ 50
lm_30_50 <- acs_hud_de_geojoined_prop %>%
    lm(data = ., eligible_renters_30pct_prop ~ eligible_renters_50pct_prop)

aug_30_50 <- lm_30_50 %>% 
    augment()


resid_plot_30_50 <- aug_30_50 %>%
    left_join(acs_hud_de_geojoined_prop %>% select(row_number, tract),
              by = c(".rownames" = "row_number")) %>% 
    ggplot(aes(x = eligible_renters_50pct_prop, y = .std.resid, label = tract)) + 
    geom_point() +
    geom_hline(yintercept = 0) +
    ylab("Standardized Residual") +
    xlab("Proportion of renters paying 50%+ on rent")

resid_plot_30_50 %>%
    ggplotly()
barplot_30_50_prop_diff <- acs_hud_de_geojoined_prop %>%
    ggplot(aes(x = reorder(tract, diff_prop_30_50), y = diff_prop_30_50)) + 
    geom_hline(yintercept = mean(acs_hud_de_geojoined_prop$diff_prop_30_50, na.rm = TRUE)) +
    geom_bar(stat = "identity") +
    xlab("Census Tracts") +
    ylab("Difference between 30% vs 50% (proportions)") 

barplot_30_50_prop_diff %>% ggplotly()
## Warning: Removed 4 rows containing missing values (position_stack).

Higher numbers mean that the census tract has higher proportions of renters paying 30% or more income on rent than those paying 50% or more income on rent.

Separating those paying 30-40% on rent and 50%+ on rent

Interaction (30-40% prop x 50%+ prop)

I ran a regression predicting the proportion of eligible renters receiving a voucher (voucher serviceability) from the proportion of renters paying 30-40% of rent and the proportion of renters paying 50% or more on rent.

Results showed that:

  • Higher proportions of non-severely burdened renters (30-40% on rent) and severely-burdened renters (50%+ on rent) were both associated with lower voucher serviceability

  • There was an interaction between the proportions of non-severe burdened renters and severely burdened renters

  • Among the census tracts with lower proportion of non-severe burdened renters, higher proportion of severely burdened renters predicted lower proportions of eligible renters receiving a voucher (lower serviceability).

  • However, among the census tracts with higher proportions of non-severely burdened renters, higher proportions of severely burdened renters predicted higher voucher serviceability.

model <- acs_hud_de_geojoined_prop %>%
    lm(data = ., formula = prop_serviced ~ rent_50_prop * rent_30to40_prop)
summary(model)
## 
## Call:
## lm(formula = prop_serviced ~ rent_50_prop * rent_30to40_prop, 
##     data = .)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.20442 -0.09208 -0.04287  0.05029  0.57459 
## 
## Coefficients:
##                               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)                    0.47596    0.06081   7.827 6.76e-13 ***
## rent_50_prop                  -2.21184    0.58543  -3.778 0.000223 ***
## rent_30to40_prop              -3.35719    0.64971  -5.167 7.08e-07 ***
## rent_50_prop:rent_30to40_prop 22.08215    6.25155   3.532 0.000540 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1469 on 158 degrees of freedom
##   (55 observations deleted due to missingness)
## Multiple R-squared:  0.1808, Adjusted R-squared:  0.1653 
## F-statistic: 11.63 on 3 and 158 DF,  p-value: 6.321e-07
library(sjPlot)
plot_model(model, type = "int", mdrt.values = "meansd")

acs_hud_de_geojoined_prop %>%
    ggplot(aes(x = rent_50_prop, y = prop_serviced)) +
    geom_point()
## Warning: Removed 55 rows containing missing values (geom_point).

Scatter Plot

scatter_nonsevere_severe <- acs_hud_de_geojoined_prop %>% 
    ggplot(aes(x = rent_30to40_prop, y = rent_50_prop, label = census_tract_label)) +
    geom_point()
scatter_nonsevere_severe %>% ggplotly()
acs_hud_de_geojoined_prop %>% 
    ggplot(aes(x = rent_30to40_prop, y = prop_serviced, label = census_tract_label)) +
    geom_point()
## Warning: Removed 55 rows containing missing values (geom_point).

acs_hud_de_geojoined_prop %>% 
    ggplot(aes(x = rent_50_prop, y = prop_serviced, label = census_tract_label)) +
    geom_point()
## Warning: Removed 55 rows containing missing values (geom_point).

How about for the vouchers?

scatter_30_50_voucher <- acs_hud_de_geojoined_prop %>% 
    ggplot(aes(x = prop_serviced, y = diff_prop_30_50, label = tract)) + 
    geom_point() +
    xlab("Proportion of eligible renters receiving a voucher") +
    ylab("Difference between 30% vs 50% (proportions)")

scatter_30_50_voucher %>% ggplotly()